package com.whately.core.base.utils;


import com.whately.core.base.constant.ConstantProject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 时间工具类
 */
public class IDCardUtil {
    private final static Logger log = LoggerFactory.getLogger(IDCardUtil.class);

    // 地区验证
    private final static List<String> aCity = Arrays.asList( "11", "12", "13", "14", "15", "21", "22", "23", "31", "32", "33", "34", "35",
            "36", "37", "41", "42", "43", "44", "45", "46", "50", "51", "52",
            "53", "54", "61", "62", "63", "64", "65", "71", "81", "82", "91");

    // 地区验证
    private final static List<String> bCityReverse = Arrays.asList( "81", "82", "91" ,"63", "53", "54", "61", "62","64", "65", "71", "14", "12",
            "13", "11", "15", "21", "22", "23", "31", "32", "33", "34", "35",
            "36", "37", "41", "42", "43", "50", "51", "52","44", "45", "46");

    public static boolean checkCertCorrect(String certNo) {
        if(StringUtils.isBlank(certNo)){
            return false;
        }

        Boolean isexists = true;// 内容是否存在
        String info = "";
        final char[] VERIFY_CODE = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' }; // 18位身份证中最后一位校验码
        final int[] VERIFY_CODE_WEIGHT = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };// 18位身份证中，各个数字的生成校验码时的权值
        // 前17位验证
        if (certNo.length() > 17) {
            int falseNum = 0;
            for (int i = 0; i < 17; i++) {
                char ch = certNo.charAt(i);
                if (!Character.isDigit(ch)) {
                    falseNum += 1;
                }
            }
            if (falseNum > 0) {
                info = "身份证前17位须为阿拉伯数字";
            } else {
                // 出身日期验证
                int falseDate = 0;
                String birthDate = certNo.substring(6, 14);
                String year = certNo.substring(6, 10);
                String month = certNo.substring(10, 12);
                String day = certNo.substring(12, 14);

                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                String str = sdf.format(new Date());

                if (Integer.parseInt(year) % 4 == 0) {
                    if (month.equals("02")) {
                        if (day.compareTo("29") > 0 || day.equals("00")) {
                            falseDate += 1;
                        }
                    } else if (Integer.parseInt(day) > 0 || Integer.parseInt(day) < 8
                            || Integer.parseInt(day) % 2 == 0) {
                        if (day.compareTo("31") > 0 || day == "00") {
                            falseDate += 1;
                        }
                    } else if (Integer.parseInt(day) > 0 || Integer.parseInt(day) < 8
                            || Integer.parseInt(day) % 2 == 1) {
                        if (day.compareTo("30") > 0 || day == "00") {
                            falseDate += 1;
                        }
                    } else if (Integer.parseInt(day) > 7 || Integer.parseInt(day) < 13
                            || Integer.parseInt(day) % 2 == 1) {
                        if (day.compareTo("31") > 0 || day == "00") {
                            falseDate += 1;
                        }
                    } else if (Integer.parseInt(day) > 7 || Integer.parseInt(day) < 13
                            || Integer.parseInt(day) % 2 == 0) {
                        if (day.compareTo("30") > 0 || day == "00") {
                            falseDate += 1;
                        }
                    }
                } else {
                    if (month.equals("02")) {
                        if (day.compareTo("28") > 0 || day.equals("00")) {
                            falseDate += 1;
                        }
                    } else if (Integer.parseInt(day) > 0 || Integer.parseInt(day) < 8
                            || Integer.parseInt(day) % 2 == 0) {
                        if (day.compareTo("31") > 0 || day == "00") {
                            falseDate += 1;
                        }
                    } else if (Integer.parseInt(day) > 0 || Integer.parseInt(day) < 8
                            || Integer.parseInt(day) % 2 == 1) {
                        if (day.compareTo("30") > 0 || day == "00") {
                            falseDate += 1;
                        }
                    } else if (Integer.parseInt(day) > 7 || Integer.parseInt(day) < 13
                            || Integer.parseInt(day) % 2 == 1) {
                        if (day.compareTo("31") > 0 || day == "00") {
                            falseDate += 1;
                        }
                    } else if (Integer.parseInt(day) > 7 || Integer.parseInt(day) < 13
                            || Integer.parseInt(day) % 2 == 0) {
                        if (day.compareTo("30") > 0 || day == "00") {
                            falseDate += 1;
                        }
                    }
                }

                if (birthDate.compareTo(str) > 0 || birthDate.compareTo("19000101") < 0 || month.compareTo("12") > 0
                        || month == "00") {
                    falseDate += 1;
                }

                if (falseDate > 0) {
                    info = "身份证上的出生日期非法";
                } else {

                    String cityID = certNo.substring(0, 2);
                    int trueCity = 0;
                    for (int i = 0; i < aCity.size(); i++) {
                        if (aCity.get(i).equals(cityID)) {
                            trueCity += 1;
                        }
                    }
                    if (trueCity == 0) {
                        info = "你的身份证地区非法";
                    } else {
                        // 校验位验证
                        int sum = 0;
                        for (int i = 0; i < 17; i++) {
                            char ch = certNo.charAt(i);
                            sum += ((int) (ch - '0')) * VERIFY_CODE_WEIGHT[i];
                        }
                        if (VERIFY_CODE[sum % 11] != certNo.toUpperCase().charAt(17)) {
                            info = "身份证号码错误";
                        } else {
                            isexists = false;
                        }
                    }
                }
            }
        } else {
            info = "身份证不能小于18位";
        }
        if (isexists) {
            log.error("IDCardUtil not correct card no {},info {} ",certNo,info);
            //throw new ServiceException(400,"身份证号不合法");
            return false;
        }
        return true;

    }

    //暂时不加密，原路返回
    public static String simpleEnCodeCert(String certNo) {
        /*String pre = certNo.substring(0,14);//年月日及之前的保持不动
        String mid = certNo.substring(14,17);
        String last = certNo.substring(17,18);

        String reverseMid = new StringBuffer(mid).reverse().toString();
        int minusValue = 999- Integer.parseInt(reverseMid);
        String mStr = StringUtils.leftPad(String.valueOf(minusValue),3,"0");
        return pre+mStr+last;*/
        return certNo;
    }


    //加密
    public static String enCodeCert(String certNo) {
       // String key = "abcdefgh88680721abcdefgh88680721";
        String pre = certNo.substring(0,14);
        //String mid = certNo.substring(14,17);
        //String last = certNo.substring(17,18);

        String last = certNo.substring(14, 18);

        String enStr= AESUtils.encrypt(ConstantProject.DEFAULT_ENCODE_KEY_16,last);

        return pre+enStr;
    }

    //解密
    private static String deCodeCert(String certNo) {

        String pre = certNo.substring(0,14);
        String enCodeText = certNo.substring(14);
      //  String key = "abcdefgh88680721abcdefgh88680721";
        String decodeStr=AESUtils.decrypt(ConstantProject.DEFAULT_ENCODE_KEY_16,enCodeText);


        return pre+decodeStr;
    }


}
